use crate::ecs::entity::Entity;
use crate::asset_manager::AssetManager;
use anyhow::Result;
use serde::Deserialize;
use std::collections::HashMap;
use uuid::Uuid;

#[derive(Deserialize, Debug)]
pub struct SceneConfig {
    pub name: String,
    pub entities: Vec<String>,
    pub background: Option<String>,
    pub music: Option<String>,
}

pub struct Scene {
    pub name: String,
    pub entities: HashMap<Uuid, Entity>,
    pub systems: Vec<Box<dyn crate::ecs::system::System>>,
    pub background: Option<String>,
    pub music: Option<String>,
}

impl Scene {
    pub fn new(name: &str) -> Self {
        Self {
            name: name.to_string(),
            entities: HashMap::new(),
            systems: Vec::new(),
            background: None,
            music: None,
        }
    }

    pub fn add_entity(&mut self, entity: Entity) {
        self.entities.insert(entity.id, entity);
    }

    pub fn get_entity(&self, id: &Uuid) -> Option<&Entity> {
        self.entities.get(id)
    }

    pub fn get_entity_mut(&mut self, id: &Uuid) -> Option<&mut Entity> {
        self.entities.get_mut(id)
    }

    pub fn add_system(&mut self, system: Box<dyn crate::ecs::system::System>) {
        self.systems.push(system);
    }

    pub fn load_from_config(&mut self, config: &SceneConfig, assets: &AssetManager) -> Result<()> {
        self.name = config.name.clone();
        self.background = config.background.clone();
        self.music = config.music.clone();
        
        // 加载场景中的实体
        for entity_name in &config.entities {
            if let Some(entity) = assets.get_entity(entity_name) {
                self.add_entity(entity.clone());
            }
        }
        
        Ok(())
    }
}

pub struct SceneManager {
    pub current_scene: String,
    pub scenes: HashMap<String, Scene>,
    pub next_scene: Option<String>,
}

impl SceneManager {
    pub fn new() -> Self {
        Self {
            current_scene: "".to_string(),
            scenes: HashMap::new(),
            next_scene: None,
        }
    }
    
    pub fn add_scene(&mut self, name: &str, scene: Scene) {
        self.scenes.insert(name.to_string(), scene);
    }
    
    pub fn get_current_scene(&mut self) -> Option<&mut Scene> {
        self.scenes.get_mut(&self.current_scene)
    }
    
    pub fn switch_scene(&mut self, scene_name: &str) {
        self.next_scene = Some(scene_name.to_string());
    }
    
    pub fn apply_scene_switch(&mut self) {
        if let Some(next) = &self.next_scene {
            if self.scenes.contains_key(next) {
                self.current_scene = next.clone();
                self.next_scene = None;
            }
        }
    }
}